package at.fhooe.pandora.entities;

import at.fhooe.engine.entity.Entity;
import at.fhooe.engine.event.events.CollisionEvent;
import at.fhooe.engine.mapobject.Wall;
import at.fhooe.engine.pandora.Game;
import at.fhooe.engine.physics.CircleBody;
import at.fhooe.engine.physics.PhysicBody;
import at.fhooe.engine.physics.forces.DampingForce;

public class BulletEntity extends Entity implements CollisionEvent.Listener {

	public static long bulletCount = 0;
	public static final String ID = "BulletEntity";
	public static final double MAX_LIFE_TIME = 3.50;

	private static double bulletSpeed = 500;
	private static DampingForce dampingForce = new DampingForce(0.3, 0.3, 0.3);
	
	private double m_bulletLifeTime;
	private PhysicBody m_physicBody;
	private double m_size;
	
	public BulletEntity(String name, String timerName, double positionX, double positionY, double positionZ, double angularPosition) {
		this(name, timerName, positionX, positionY, positionZ, angularPosition, 10);
	}
	
	public BulletEntity(String name, String timerName, double positionX, double positionY, double positionZ, double angularPosition, double size) {
		super(ID, name);
		m_size = size;
		
		m_physicBody = new CircleBody(name, m_size, true);
		m_physicBody.setTimer(timerName);
		m_physicBody.setPosition(positionX, positionY, positionZ);
		m_physicBody.setAngularPosition(angularPosition);
		m_physicBody.addForce(dampingForce);
		m_physicBody.setSpeedInDirection(bulletSpeed);
		
		bulletCount++;
		
		m_bulletLifeTime = m_physicBody.getTimer().getTotalElapsedTime();
	}
	
	public void setPosition(double positionX, double positionY, double positionZ, double angularPosition) {
		m_physicBody.setPosition(positionX, positionY, positionZ);
		m_physicBody.setAngularPosition(angularPosition);
	}
	
	public double getSize() {
		return m_size;
	}

	protected void initialize() {
		Game.getInstance().getPhysicsManager().addPhysicBody(m_physicBody);
		Game.getInstance().getEventManager().addListener(this, CollisionEvent.TYPE);
	}
	
	protected void deinitialize() {
		Game.getInstance().getPhysicsManager().removePhysicBody(m_physicBody);
		Game.getInstance().getEventManager().removeListener(this, CollisionEvent.TYPE);
	}
	
	public void update() {
		limitWorldPosition();
		
		if (m_bulletLifeTime + MAX_LIFE_TIME < m_physicBody.getTimer().getTotalElapsedTime()) {
			Game.getInstance().getEntityManager().removeEntity(this);
		}
	}
	
	//TODO remove duplicated code
	private void limitWorldPosition() {
		int offset = 30;
		//TODO The state should handle this
		int width = (int) (	Game.getInstance().getGraphicsSystem().getWidth() /
				Game.getInstance().getGraphicsSystem().getScaleX());
		int height = (int) (Game.getInstance().getGraphicsSystem().getHeight() /
				Game.getInstance().getGraphicsSystem().getScaleY());

		if (m_physicBody.getPositionX() > width + offset) {
			m_physicBody.setPosition(0 - offset, m_physicBody.getPositionY(), 0.0);
		} else if (m_physicBody.getPositionX() < 0 - offset) {
			m_physicBody.setPosition(width + offset, m_physicBody.getPositionY(), 0.0);
		}
		
		if (m_physicBody.getPositionY() > height + offset) {
			m_physicBody.setPosition(m_physicBody.getPositionX(), 0 - offset, 0.0);
		} else if (m_physicBody.getPositionY() < 0 - offset) {
			m_physicBody.setPosition(m_physicBody.getPositionX(), height + offset, 0.0);
		}
	}
	
	public void onCollisionEvent(CollisionEvent collisionEvent) {
		if(collisionEvent.isEntityInvolved(m_name)) {
			Object opponent = collisionEvent.getOpponent(m_name);
			if (opponent instanceof AsteroidEntity) {
				Game.getInstance().getEntityManager().removeEntity(m_name);
			} else if(opponent instanceof Wall) {
				Game.getInstance().getEntityManager().removeEntity(m_name);
			}
		}
	}

	@Override
	public double[] getDebug() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public PhysicBody getPhysicBody() {
		// TODO Auto-generated method stub
		return m_physicBody;
	}

}
